package io.jt808.multiService;

import io.jt808.proto.Wrapper;
import io.jt808.proto.down.JT8003;
import io.norland.server.ChannelHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
public class PackageService {
    @Autowired
    private PackageHolder packageHolder;

    long intiDelay = 1000;
    long delay = 1000 * 6;
    long timeout = 1000 * 5;
    int maxRetransTimes = 3;

    @PostConstruct
    public void postStart() {
        scheduledThreadPoolExecutorStart();
    }

    private void scheduledThreadPoolExecutorStart() {
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor =
                new ScheduledThreadPoolExecutor(1);
        scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> pollAndSend(),
                intiDelay, delay, TimeUnit.MILLISECONDS);
    }

    private void pollAndSend() {
        Set<String> hkeys = packageHolder.getHashKeySet();
        for (String hkey : hkeys) {
            PackageItem packageItem = packageHolder.getPackageItem(hkey);
            if (packageItem.getRetransmissionTimes() > maxRetransTimes) {
                packageHolder.remove(hkey);
                continue;
            }
            long cutTime = System.currentTimeMillis() - packageItem.getUpdateTime();
            if (cutTime >= maxRetransTimes * delay) {
                packageHolder.remove(hkey);
                continue;
            }
            if (cutTime > timeout) {
                if (ChannelHolder.containsKey(packageItem.getTerminalSerialNo())) {
                    JT8003 jt8003 = new JT8003();
                    jt8003.setResponseMessageSerialNo(packageItem.getMessageSerialNo());
                    List<Integer> vl = packageItem.getRetransmissionPackIds();
                    jt8003.setRetransmissionCount((byte) vl.size());
                    jt8003.setRetransmissionPacketNos(vl);
                    ChannelHolder.writeAndFlush(packageItem.getTerminalSerialNo(), jt8003);
                    packageItem.setUpdateTime(System.currentTimeMillis());
                    packageItem.increaseRetransmissionTimes();
                    packageHolder.update(hkey, packageItem);
                }
            }
        }
    }
}
